home *** CD-ROM | disk | FTP | other *** search
- {
-
- Peterborough, Ontario, CANADA
-
- Hi !
-
- If any of you boys have been reading BYTE magazine, you may have
- noticed an article in the Dec/93 issue on Directory objects (in
- C++ however). I was keenly interested in this article, because it
- showed a quick and easy way to handle directory recursion - which
- was necessary for a project I was doing.
-
- While the complete code listings weren't given, they were in C so
- I couldn't use them directly anyways, so I just wrote my own
- object in TP. (Works great, btw)
-
- I've decided to wake this conference up a bit so I'm going to post
- this stuff over the next couple of days. The first installment is
- the SORT unit which implements a binary-tree sorting object for
- the sort method of the directory object. This object is completely
- re-usable and extendable (designed so from the ground up) and
- helps demonstrate more uses for OOP.
- ----------------------------------------------------------------------
- }
- Unit SORT;
-
- INTERFACE
-
- TYPE
- comparefunc = function(d1, d2 :pointer):integer;
- { function returns sort value for data }
- ptree = ^treenode;
- treenode = record
- data :pointer;
- left,
- right :ptree;
- end;
- { ****** Abstract sort object ******
- Must be inherited
- }
- pSortTree = ^oSortTree;
- oSortTree = OBJECT
- root :ptree;
- comp :comparefunc;
-
- constructor Init(cf :comparefunc);
- destructor Done;
-
- procedure InsertNode(n :pointer);
- procedure DeleteNode(var Node); virtual; { abstract }
- function ReadLeftNode:pointer;
- end;
-
- IMPLEMENTATION
-
- constructor oSortTree.Init(cf :comparefunc);
- begin
- FillChar(self, SizeOf(self), #0); { zero out object data }
- comp := cf; { set "compare" function to user defined far-local }
- end;
-
- destructor oSortTree.Done;
-
- procedure disposetree(var t :ptree);
- begin
- if t=NIL then
- EXIT;
- disposetree(t^.left);
- disposetree(t^.right);
- DeleteNode(t^.data);
- dispose(t);
- end;
-
- begin
- disposetree(root);
- end;
-
- procedure oSortTree.InsertNode(n :pointer);
- { Insert the data pointer in sorted order, as defined by the
- passed "compare" function
- }
- procedure recursetree(var t :ptree);
-
- procedure PutNode(node :ptree);
- begin
- node^.right := NIL;
- node^.left := NIL;
- node^.data := n;
- end;
-
- begin
- if comp(n, t^.data)>0 then
- begin
- if t^.right<>NIL then
- recursetree(t^.right)
- else
- begin
- New(t^.right);
- PutNode(t^.right);
- end;
- end
- else
- begin
- if t^.left<>NIL then
- recursetree(t^.left)
- else
- begin
- New(t^.left);
- PutNode(t^.left);
- end;
- end;
- end;
-
- begin
- if n<>NIL then
- if root=NIL then
- begin
- New(root);
- root^.left := NIL;
- root^.right := NIL;
- root^.data := n;
- end
- else
- recursetree(root);
- end;
-
- procedure oSortTree.DeleteNode(var Node);
- { The calling code must define how to dispose of the data field
- by inheritance }
- begin
- Halt(255); {abstract method}
- end;
-
- function oSortTree.ReadLeftNode:pointer;
- { This function is intended to be called one-at-a-time to recover
- data in sorted order. The data is returned as an untyped
- pointer. It is assumed that the calling code will type the
- pointer as required. The data pointer is set to NIL after being
- passed to the caller. }
- var
- ln :pointer;
-
- procedure recurseTree(var t :pTree;var result :pointer);
- begin
- if t^.left<>NIL then
- begin
- recurseTree(t^.left, result);
- if result=NIL then
- begin
- result := t^.data;
- t^.data := NIL;
- end;
- end
- else
- begin
- if t^.data<>NIL then
- begin
- result := t^.data;
- t^.data := NIL;
- end
- else
- if t^.right<>NIL then
- begin
- recurseTree(t^.right, result);
- if result=NIL then
- begin
- dispose(t);
- t := NIL;
- end
- end
- else
- begin
- dispose(t);
- t := NIL;
- result := NIL;
- end;
- end;
- end;
-
- begin
- if root<>NIL then
- begin
- recurseTree(root, ln);
- ReadLeftNode := ln;
- end
- else
- ReadLeftNode := NIL;
- end;
-
- END.